package com.sc.vipface.tasks;

import com.sc.vipface.configs.SysSettings;
import com.sc.vipface.entity.bo.DeviceMemBo;
import com.sc.vipface.entity.dto.HKData;
import com.sc.vipface.entity.params.DeviceParam;
import com.sc.vipface.services.HKCameraService;
import com.sc.vipface.services.IotPlatformService;
import com.sc.vipface.utils.DtoUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Component
public class HKCameraTask extends Thread {
    private final HKCameraService hkCameraService;

    private final IotPlatformService iotPlatformService;
    private final HeartBeatTask heartBeatTask;
    private final SysSettings settings;

    private final ConcurrentHashMap<String, DeviceMemBo> deviceDict = new ConcurrentHashMap<>();

    @Override
    public void run() {
        log.info("HKCamera Task started");
        while (true) {
            try {
                var adapterDto = DtoUtils.createAdapterDto(LocalDateTime.now(), settings);
                heartBeatTask.updateDto(adapterDto);

                refreshDevices();
                TaskUtils.registerOrUpdateDevices(deviceDict, iotPlatformService, settings);
            } catch (Exception e) {
                log.warn(e.getMessage());
            }

            try {
                Thread.sleep(settings.getFetchInterval());
            } catch (Exception e) {
                log.warn(e.getMessage());
            }
        }
    }

    private void refreshDevices() {
        int pageNum = 1;
        int pageSize = 100;

        while (true) {
            log.debug("refresh devices from {}", pageNum * pageSize);
            DeviceParam param = new DeviceParam();
            param.setPageNo(pageNum);
            param.setPageSize(pageSize);

            HKData data = hkCameraService.getDeviceList(param);

            if (data == null || CollectionUtils.isEmpty(data.list)) {
                log.info("Get no devices");
                return;
            }

            List<DeviceMemBo> batchDevices = new ArrayList<>();
            var devices = data.getList();
            // Debug
            var deviceLogs = devices.stream().map(d -> "{" + d.getIndexCode() + ":" + d.getName() + ":" + d.getIsOnline() + "}").collect(Collectors.joining(","));
            log.info("Get {} device with page {}: {}", devices.size(), pageNum, deviceLogs);
            for (var device : devices) {
                var id = device.getIndexCode();
                // 海康开放平台没有上报online，所以设定online=1
    //            int online = Objects.equals(device.getStatus(), "1") ? 1 : 0;
                int online = Objects.equals(device.getIsOnline(), "online") ? 1 : 0;
                var deviceMem = deviceDict.get(id);
                if (deviceMem != null) {
                    if (!deviceMem.getRegistered()) {
                        log.debug("Device {} added but not registered, registering", id);
                        TaskUtils.registerAndUpdateDevice(deviceMem, iotPlatformService, settings);
                    }

                    if (online != deviceMem.getOnline()) {
                        log.debug("device {} status changed from {} to {}", device.getIndexCode(), deviceMem.getOnline(), online);
                        deviceMem.setOnline(online);
                        deviceMem.setStatusChanged(true);
                    }
                    batchDevices.add(deviceMem);
//                    TaskUtils.updateOnline(deviceMem, iotPlatformService, settings);
//                    continue;
                } else {
                    DeviceMemBo deviceMemBo = new DeviceMemBo();
                    deviceMemBo.setId(device.getIndexCode());
                    deviceMemBo.setName(device.getName());
                    deviceMemBo.setLat("");
                    deviceMemBo.setLng("");
                    deviceMemBo.setDevType(settings.getDeviceType());
                    deviceMemBo.setOnline(online);
                    deviceMemBo.setRegistered(false);

                    batchDevices.add(deviceMemBo);
                    log.debug("get new device {}", device.getIndexCode());
                    deviceDict.put(device.getIndexCode(), deviceMemBo);
                    log.info("try register new device {}-{}", device.getIndexCode(), device.getName());
                    TaskUtils.registerAndUpdateDevice(deviceMemBo, iotPlatformService, settings);
                    log.info("Send telemetry for new device {}", device.getIndexCode());
//                    TaskUtils.updateOnline(deviceMemBo, iotPlatformService, settings);
                }
            }

            if (!batchDevices.isEmpty()) {
                TaskUtils.UpdateOnlineBatch(batchDevices, iotPlatformService, settings);
            }
            if (data.getTotal() < pageSize) {
                log.debug("Finished last device page of {}", data.getTotal());
                return;
            }

            pageNum++;
        }
    }
}
